package com.chenfan.mcn.rule;

import com.chenfan.mcn.clients.baseinfo.BaseCustomer;
import com.chenfan.mcn.clients.privilege.DepartmentVO;
import com.chenfan.mcn.clients.privilege.SUser;
import com.chenfan.mcn.constant.NumberCst;
import com.chenfan.mcn.enums.DeleteEnum;
import com.chenfan.mcn.enums.IncomeContractTypeEnum;
import com.chenfan.mcn.extension.rule.ComputableRule;
import com.chenfan.mcn.model.BusinessCommissionDetailTemporary;
import com.chenfan.mcn.model.CustomerTarget;
import com.chenfan.mcn.model.DepartmentTarget;
import com.chenfan.mcn.model.vo.QuarterIncomeContractVO;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * 佣金提成规则V2
 *
 * @author wulg
 * @date 2021-09-22
 **/
public class BusinessCommissionV2Rule implements ComputableRule<BusinessCommissionRuleContext, List<BusinessCommissionDetailTemporary>> {

    private final static BigDecimal PERCENT_30 = new BigDecimal("0.3");

    private final static BigDecimal PERCENT_2 = new BigDecimal("0.02");

    private final static BigDecimal PERCENT_1 = new BigDecimal("0.01");

    private final static BigDecimal PERCENT_POINT_5 = new BigDecimal("0.005");

    private final static String BRAND_DIRECT_CUSTOMER = "Brand_direct_customer";

    /**
     * 组装提成人明细数据
     *
     * @param context 上下文
     */
    @Override
    public List<BusinessCommissionDetailTemporary> execute(BusinessCommissionRuleContext context) {
        QuarterIncomeContractVO x = context.getQuarterIncomeContractVO();
        BusinessCommissionDetailTemporary temporary = new BusinessCommissionDetailTemporary();
        temporary.setIncomeCode(x.getContractCode());
        temporary.setIncomeId(x.getId());
        temporary.setCustomerId(x.getCustomerId());
        temporary.setBusinessAmount(x.getBusinessAmount());
        temporary.setPayBackStatus(x.getPayBackStatus());
        temporary.setSignDate(x.getSignDate());
        temporary.setCustomerScore(context.getBaseCustomer(x.getCustomerId()).getCustomerScore());
        temporary.setCustomerFirstOrder(x.getCustomerFirstOrder() ? NumberCst.ONE : NumberCst.ZERO);
        temporary.setReturnRate(x.getReturnRate());
        temporary.setReturnFactor(x.getReturnFactor());
        temporary.setCommissionId(x.getOwnerId());
        temporary.setCommissionName(x.getOwnerName());
        temporary.setCreateDate(x.getCreateDate());
        temporary.setCreateBy(x.getOperatorId());
        temporary.setIsDelete(DeleteEnum.FALSE.getValue());
        temporary.setIsSave(NumberCst.ZERO);
        temporary.setIsInvalid(NumberCst.ZERO);
        temporary.setTemporaryCode(context.getTemporaryCode());
        this.customerTargetAchievementRate(temporary, x, context);
        if (IncomeContractTypeEnum.isLiveContract(x.getContractType()) || IncomeContractTypeEnum.isFrameContract(x.getContractType())) {
            BigDecimal projectSales = ObjectUtils.defaultIfNull(x.getLiveAmount(), BigDecimal.ZERO).multiply(PERCENT_30).add(ObjectUtils.defaultIfNull(x.getAdAmount(), BigDecimal.ZERO)).setScale(2, BigDecimal.ROUND_HALF_UP);
            temporary.setProjectSales(projectSales);
        } else {
            temporary.setProjectSales(x.getBusinessAmount());
        }
        this.departmentTargetAchievementRate(temporary, x, context);
        if (Objects.nonNull(x.getOwnerId()) && Objects.nonNull(context.getSuser(x.getOwnerId()))) {
            temporary.setJobNumber(context.getSuser(x.getOwnerId()).getJobNumber());
        }
        if (Objects.nonNull(x.getDepartmentHeaderId()) && Objects.nonNull(context.getSuser(x.getDepartmentHeaderId()))) {
            temporary.setDepartmentJobNumber(context.getSuser(x.getDepartmentHeaderId()).getJobNumber());
        }
        BigDecimal generalPoints = this.getGeneralPoints(context.getSuser(x.getOwnerId()), temporary, x, context.getBaseCustomer(x.getCustomerId()));
        temporary.setGeneralPoints(generalPoints);
        //个人提成=项目销售额*个人总提点
        BigDecimal personalCommission = temporary.getProjectSales().multiply(generalPoints).setScale(2, BigDecimal.ROUND_HALF_UP);
        temporary.setPersonalCommission(personalCommission);
        //业绩共享人
        if (NumberCst.ONE.equals(x.getPerformanceShare())) {
            BusinessCommissionDetailTemporary sharerTemporary = new BusinessCommissionDetailTemporary();
            BeanUtils.copyProperties(temporary, sharerTemporary);
            sharerTemporary.setGeneralPoints(null);
            sharerTemporary.setPersonalCommission(null);
            this.sharerTemporary(sharerTemporary, x, context);
            return Arrays.asList(temporary, sharerTemporary);
        }
        return Arrays.asList(temporary);
    }

    /**
     * 部门目标达成率
     *
     * @param temporary
     * @param x
     * @param context
     */
    private void departmentTargetAchievementRate(BusinessCommissionDetailTemporary temporary, QuarterIncomeContractVO x, BusinessCommissionRuleContext context) {
        DepartmentVO departmentVO = context.getDepartmentVO(x.getOwnerId());
        Long backupDepartmentHeadId = departmentVO != null ? departmentVO.getDepartmentHeadId() : null;
        String backupDepartmentHeadName = departmentVO != null ? departmentVO.getDepartmentHeadName() : null;
        temporary.setDepartmentHeadId(Objects.nonNull(x.getDepartmentHeaderId()) ? x.getDepartmentHeaderId() : backupDepartmentHeadId);
        temporary.setDepartmentHeadName(Objects.nonNull(x.getDepartmentHeaderName()) ? x.getDepartmentHeaderName() : backupDepartmentHeadName);
        DepartmentTarget departmentTarget = context.getDepartmentTarget(x.getQuarterCode(), x.getDepartmentId());
        if (Objects.nonNull(departmentTarget) && Objects.nonNull(departmentTarget.getTargetReachRate())) {
            temporary.setDepartmentTargetAchievementRate(departmentTarget.getTargetReachRate());
        } else {
            temporary.setDepartmentTargetAchievementRate(BigDecimal.ZERO);
        }
        if (Objects.nonNull(temporary.getDepartmentHeadId()) && temporary.getDepartmentHeadId().longValue() != temporary.getCommissionId().longValue()) {
            Integer userStatus = context.getSuser(temporary.getDepartmentHeadId()).getStatus();
            if (userStatus.equals(NumberCst.ONE) || userStatus.equals(NumberCst.TWO)) {
                temporary.setDepartmentHeadCommissionPoint(BigDecimal.ZERO);
            } else {
                temporary.setDepartmentHeadCommissionPoint(PERCENT_1);
            }
            //负责人提成=项目销售额*客户目标达成率*回款系数*部门负责人提点
            BigDecimal departmentHeadCommission = temporary.getProjectSales().multiply(temporary.getDepartmentHeadCommissionPoint())
                    .multiply(temporary.getTargetAchievementRate())
                    .multiply(x.getReturnFactor()).setScale(2, BigDecimal.ROUND_HALF_UP);
            temporary.setDepartmentHeadCommission(departmentHeadCommission);
        } else {
            temporary.setDepartmentHeadCommissionPoint(BigDecimal.ZERO);
            temporary.setDepartmentHeadCommission(BigDecimal.ZERO);
        }

    }

    /**
     * （客户）目标达成率
     *
     * @param temporary
     * @param x
     * @param context
     */
    private void customerTargetAchievementRate(BusinessCommissionDetailTemporary temporary, QuarterIncomeContractVO x, BusinessCommissionRuleContext context) {
        CustomerTarget customerTarget = context.getCustomerTarget(x.getQuarterCode(), x.getCustomerId());
        temporary.setKeyCustomers(Objects.nonNull(customerTarget) ? NumberCst.ZERO : NumberCst.ONE);
        if (Objects.isNull(customerTarget)) {
            temporary.setTargetAchievementRate(BigDecimal.ONE);
        } else if (Objects.isNull(customerTarget.getTargetReachRate())) {
            temporary.setTargetAchievementRate(BigDecimal.ZERO);
        } else if(customerTarget.getTargetReachRate().compareTo(BigDecimal.ONE) == 1) {
            temporary.setTargetAchievementRate(BigDecimal.ONE);
        } else {
            temporary.setTargetAchievementRate(customerTarget.getTargetReachRate());
        }
    }

    /**
     * 共享人提成数据组装
     *
     * @param temporary {@link BusinessCommissionDetailTemporary}
     * @param x         {@link QuarterIncomeContractVO}
     * @param context
     */
    private void sharerTemporary(BusinessCommissionDetailTemporary temporary, QuarterIncomeContractVO x, BusinessCommissionRuleContext context) {
        temporary.setCommissionId(x.getPerformanceSharerId());
        temporary.setCommissionName(x.getPerformanceSharerName());
        temporary.setDepartmentHeadCommissionPoint(BigDecimal.ZERO);
        temporary.setDepartmentHeadCommission(BigDecimal.ZERO);
        if (Objects.nonNull(x.getPerformanceSharerId()) && Objects.nonNull(context.getSuser(x.getPerformanceSharerId()))) {
            temporary.setJobNumber(context.getSuser(x.getPerformanceSharerId()).getJobNumber());
        }
        SUser sUser = context.getSuser(x.getPerformanceSharerId());
        if (sUser == null || sUser.getStatus().equals(NumberCst.ONE) || sUser.getStatus().equals(NumberCst.TWO)) {
            //离职
            temporary.setGeneralPoints(BigDecimal.ZERO);
        } else {
            //在职
            temporary.setGeneralPoints(PERCENT_POINT_5);
        }
        //个人提成=项目销售额*个人总提点
        BigDecimal personalCommission = temporary.getProjectSales().multiply(temporary.getGeneralPoints())
                .setScale(2, BigDecimal.ROUND_HALF_UP);
        temporary.setPersonalCommission(personalCommission);
    }

    /**
     * 获取个人提点
     *
     * @return
     */
    private BigDecimal getGeneralPoints(SUser sUser, BusinessCommissionDetailTemporary temporary, QuarterIncomeContractVO x, BaseCustomer customer) {
        //是否离职 是
        if (sUser == null || sUser.getStatus().equals(NumberCst.ONE) || sUser.getStatus().equals(NumberCst.TWO)) {
            return BigDecimal.ZERO;
        }
        //是否是直播合同 是
        if (IncomeContractTypeEnum.isLiveContract(x.getContractType())) {
            return PERCENT_1;
        }
        //是否为保护客户 非
        if (NumberCst.ONE.equals(temporary.getKeyCustomers())) {
            return x.getCustomerFirstOrder().booleanValue() ? PERCENT_2 : PERCENT_1;
        }
        //是否为渠道客户 非
        if (BRAND_DIRECT_CUSTOMER.equalsIgnoreCase(customer.getCustomerClassification())){
            return x.getCustomerFirstOrder().booleanValue() ? PERCENT_2 : PERCENT_1;
        }
        return x.getCustomerFirstOrder().booleanValue() ? PERCENT_1 : PERCENT_POINT_5;
    }
}
